#include "header.h"

int opcode7 (unsigned short inst)
{
	if (!(inst & 000400))	// Group 1 Microinstruction
							// Bit3=0 
	{
		if (!(inst & 000777)) // No operation if lower order 9 bits cleared
			NOP (inst); 
		else
		{
			if (inst & 00200) CLA(inst);	// Sequence 1
			if (inst & 00100) CLL(inst);

			if (inst & 00040) CMA(inst);	// Sequence 2
			if (inst & 00020) CML(inst);	

			if (inst & 00001) IAC(inst);	// Sequence 3

			if ((inst & 00012) == 00012) RTR(inst);	// Sequence 4
			else if (inst & 00010) RAR(inst);
			else if ((inst & 00006) == 00006) RTL(inst);
			else if (inst & 00004) RAL(inst);
			else;
		}
	}
	else if ((inst & 000400) && !(inst & 000001)) // Group 2 Microinstruction
	{											// Bit3=1,Bit11=0
		switch (inst & 00170)	// Sequence 1
		{
			case 00010: SKP(inst); break;	//SKP

			//AND Subgroup combinations
			case 00110: SPA(inst); break;	//SPA
			case 00030: SZL(inst); break;	//SZL			
			case 00050: SNA(inst); break;	//SNA
			case 00070: SNASZL(inst); break; //SNA SZL
			case 00130: SPASZL(inst); break; //SPA SZL
			case 00150: SPASNA(inst); break;	//SPASNA
			case 00170: SPASNASZL(inst); break;
			
			
			//OR Subgroup combinations
			case 00100:	SMA(inst);			break; // SMA
			case 00040: SZA(inst);			break; // SZA
			case 00140: SMASZA(inst);		break; // SMA SZA
			case 00020: SNL(inst);			break; // SNL
			case 00120: SMASNL(inst);		break; // SMA SNL
			case 00060: SZASNL(inst);		break; // SZA SNL
			case 00160: SMASZASNL(inst);	break; // SMA SZA SNL

			default:;
		}
		
		if (inst & 00200) CLA(inst);	// Sequence 2

		if (inst & 00004) OSR(inst);	// Sequence 3
		if (inst & 00002) HLT(inst);
	}
	else if ((inst & 01001)) // Group 3 Microinstruction
	{						 // Bit3=1,Bit11=1
		// No-op
	}
	else;

	return 0;
}

int NOP (unsigned short inst)
{
	// No-op

	return 0;
}

int CLA (unsigned short inst) //CLear Accumulator
{
	LB_AC &= 010000;//Bit-wise AND LB_AC with mask 10000o
					//to clear low order 12 bits

	return 0;
}

int CLL (unsigned short inst) //CLear Link
{
	LB_AC &= 007777; //Bit-wise AND LB_AC with mask 07777o
					 //to clear bit 12 to bit 14.

	return 0;
}

int CMA (unsigned short inst) //CoMplement Accumulator
{
	unsigned short tmp = 0;

	tmp = LB_AC & 007777;//Bit-wise AND LB_AC with mask 07777o
						 //to leave accumulator bits

	tmp = ~tmp; //Bit-wise complement of the accumulator bits

	tmp &= 007777;//Bit-wise AND LB_AC with mask 07777o
				 //to leave the result of the bit-wise complement
	
    LB_AC &= 010000;//Bit-wise AND LB_AC with mask 010000o
					//to clear accumulator bits

	LB_AC |= tmp;//Bit-wise OR LB_AC with complemented accumulator bits

	return 0;
}

int CML (unsigned short inst) //CoMplement Link
{
	unsigned short tmp = 0;

	tmp = LB_AC & 010000;//Bit-wise AND LB_AC with mask 10000o
						 //to leave the link bit

	tmp = ~tmp; //Bit-wise complement of the link bit

	tmp &= 010000;//Bit-wise AND LB_AC with mask 10000o
				 //to leave the result of the bit-wise complement
	
    LB_AC &= 007777;//Bit-wise AND LB_AC with mask 07777o
					//to clear link bits

	LB_AC |= tmp;//Bit-wise OR LB_AC with complemented link bits

	return 0;
}

int IAC(unsigned short inst) //Increment ACumulator
{
	++LB_AC;	//Increment LB_AC

	if(LB_AC == 020000)  //Check if the result exceeded 13-bit boundary
		LB_AC = 0;		 //and clear all bits if it did.

	return 0;
}

int RAR(unsigned short inst)
{
	unsigned short lsb = 0;

	lsb = LB_AC & 0000001;
	lsb <<= 12;

  //rotate LB_AC Right once
  LB_AC >>= 1;
  LB_AC |= lsb;

  LB_AC &= 017777; // AND with maks 017777 to leave low order 13 bits only
  
  return 0;
}


int RTR(unsigned short inst)
{
	unsigned short lsb = 0;

	lsb = LB_AC & 0000003;
	lsb <<= 11;

  //rotate LB_AC Right twice
  LB_AC >>= 2;
  LB_AC |= lsb;

  LB_AC &= 017777; // AND with maks 017777 to leave low order 13 bits only
  
  return 0;
}



int RAL(unsigned short inst)
{
	unsigned short msb = 0;
	
	msb = LB_AC & 010000;
	msb >>= 12;

  //rotate LB_AC Left once
  LB_AC <<= 1;
  LB_AC |= msb;

  LB_AC &= 017777; // AND with maks 017777 to leave low order 13 bits only
  
  return 0;
}


int RTL(unsigned short inst)
{
	unsigned short msb = 0;
	
	msb = LB_AC & 016000;
	msb >>= 11;
	
  //rotate LB_AC Left twice
  LB_AC <<= 2;
  LB_AC |= msb;

  LB_AC &= 017777; // AND with maks 017777 to leave low order 13 bits only
  
  return 0;
}